﻿using DataProcessor.EF;
using Hjt212Parser;
using log4net;
using System;
using System.Linq;

namespace DataProcessor.Process
{
    public static class DataInstructionProcessor
    {
        private static readonly ILog Log = LogManager.GetLogger(typeof(DataInstructionProcessor));
        //实时数据指令
        public static void Process2011(string content)
        {
            try
            {
                var mn = Parser.GetStringByKey("MN", content);
                if (string.IsNullOrWhiteSpace(mn))
                {
                    return;
                }

                var port = Util.GetInfoFromMn(mn);
                if (port == null)
                {
                    Log.Warn("MN：" + mn + " 找不到对应企业排口！");
                    return;
                }
                var dataTime = Parser.GetDateTimeByKey("DataTime", content);
                if (dataTime == null)
                {
                    Log.Warn("没有时间！");
                    return;
                }
                var dataTimeValue = dataTime.Value;
                var pollutantCodes = Parser.GetPollutantCodes(content);

                using (var contextTarget = new PlatformVocContext())
                {
                    //todo:性能会有问题。
                    //var master = contextTarget.data_realtime_main.Where(t => t.ps_code.Equals(port.ps_code)).Where(t => t.pi_code.Equals(port.port_code))
                    //    .FirstOrDefault(t => t.monitor_time == dataTimeValue);
                    data_realtime_main master = null;
                    if (master == null)
                    {
                        master = new data_realtime_main
                        {
                            mn = mn,
                            monitor_time = dataTimeValue,
                            is_synchronize = false,
                            ps_code = port.ps_code,
                            pi_code = port.port_code,
                            type = "voc"
                        };
                        contextTarget.data_realtime_main.Add(master);
                        contextTarget.SaveChanges();

                        foreach (var detailCode in pollutantCodes)
                        {
                            var factor = Util.GetFactor(detailCode);
                            if (factor == null)
                            {
                                Log.Warn("Factor：" + detailCode + " 找不到污染物因子！");
                                continue;
                            }

                            var rtdDouble = Parser.GetFloatByKey(detailCode + "-Rtd", content);
                            if (rtdDouble == null)
                            {
                                Log.Warn("Rtd：没有RTD！");
                                continue;
                            }

                            //var detail = contextTarget.data_realtime.Where(t => t.main_id == master.id)
                            //    .FirstOrDefault(t => t.pollutant_code.Equals(detailCode));
                            data_realtime detail = null;
                            if (detail == null)
                            {
                                detail = new data_realtime();
                                contextTarget.data_realtime.Add(detail);
                            }

                            detail.main_id = master.id;
                            detail.Cou = rtdDouble.Value;
                            detail.Min = rtdDouble.Value;
                            detail.Avg = rtdDouble.Value;
                            detail.Max = rtdDouble.Value;
                            detail.pollutant_code = factor.code;

                        }

                        contextTarget.SaveChanges();
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex + Environment.NewLine + content);
            }
        }
        //分钟数据处理
        public static void Process2051(string content)
        {
            try
            {
                var mn = Parser.GetStringByKey("MN", content);
                if (string.IsNullOrWhiteSpace(mn))
                {
                    return;
                }

                var port = Util.GetInfoFromMn(mn);
                if (port == null)
                {
                    Log.Warn("MN：" + mn + " 找不到对应企业排口！");
                    return;
                }
                var dataTime = Parser.GetDateTimeByKey("DataTime", content);
                if (dataTime == null)
                {
                    Log.Warn("没有时间！");
                    return;
                }
                var dataTimeValue = dataTime.Value;
                var pollutantCodes = Parser.GetPollutantCodes(content);

                using (var contextTarget = new PlatformVocContext())
                {
                    //todo:性能会有问题。
                    data_minute_main
                        master = null; //contextTarget.data_hour_main.Where(t => t.ps_code.Equals(port.ps_code)).Where(t => t.pi_code.Equals(port.port_code))
                    //.FirstOrDefault(t => t.monitor_time == dataTimeValue);

                    if (master == null)
                    {
                        master = new data_minute_main
                        {
                            mn = mn,
                            monitor_time = dataTimeValue,
                            is_synchronize = false,
                            ps_code = port.ps_code,
                            pi_code = port.port_code,
                            type = "voc",
                            qn = dataTimeValue.ToString("yyyyMMddHHmmssfff")
                        };
                        contextTarget.data_minute_main.Add(master);
                        contextTarget.SaveChanges();


                        foreach (var detailCode in pollutantCodes)
                        {
                            var factor = Util.GetFactor(detailCode);
                            if (factor == null)
                            {
                                Log.Warn("Factor：" + detailCode + " 找不到污染物因子！");
                                continue;
                            }

                            var rtdDouble = Parser.GetFloatByKey(detailCode + "-Cou", content);
                            if (rtdDouble == null)
                            {
                                Log.Warn("Cou：没有Cou！");
                                continue;
                            }

                            //var detail = contextTarget.data_minute.Where(t => t.main_id == master.id)
                            //    .FirstOrDefault(t => t.pollutant_code.Equals(detailCode));
                            data_minute detail = null;
                            if (detail == null)
                            {
                                detail = new data_minute();
                                contextTarget.data_minute.Add(detail);
                            }

                            detail.main_id = master.id;
                            detail.Cou = rtdDouble.Value;
                            detail.Min = Parser.GetFloatByKey(detailCode + "-Min", content);
                            detail.Avg = Parser.GetFloatByKey(detailCode + "-Avg", content);
                            detail.Max = Parser.GetFloatByKey(detailCode + "-Max", content);
                            detail.pollutant_code = factor.code;
                        }

                        contextTarget.SaveChanges();
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex);
                Log.Error(content);
            }
        }
        //小时数据处理
        public static void Process2061(string content)
        {
            try
            {
                var mn = Parser.GetStringByKey("MN", content);
                if (string.IsNullOrWhiteSpace(mn))
                {
                    return;
                }

                var port = Util.GetInfoFromMn(mn);
                if (port == null)
                {
                    Log.Warn("MN：" + mn + " 找不到对应企业排口！");
                    return;
                }
                var dataTime = Parser.GetDateTimeByKey("DataTime", content);
                if (dataTime == null)
                {
                    Log.Warn("没有时间！");
                    return;
                }
                var dataTimeValue = dataTime.Value;
                var pollutantCodes = Parser.GetPollutantCodes(content);

                using (var contextTarget = new PlatformVocContext())
                {
                    //todo:性能会有问题。
                    var master = contextTarget.data_hour_main.Where(t => t.ps_code.Equals(port.ps_code)).Where(t => t.pi_code.Equals(port.port_code))
                        .FirstOrDefault(t => t.monitor_time == dataTimeValue);

                    if (master == null)
                    {
                        master = new data_hour_main
                        {
                            mn = mn,
                            monitor_time = dataTimeValue,
                            is_synchronize = false,
                            ps_code = port.ps_code,
                            pi_code = port.port_code,
                            type = "voc",
                            qn = dataTimeValue.ToString("yyyyMMddHHmmssfff")
                        };
                        contextTarget.data_hour_main.Add(master);
                        contextTarget.SaveChanges();
                    }

                    foreach (var detailCode in pollutantCodes)
                    {
                        var factor = Util.GetFactor(detailCode);
                        if (factor == null)
                        {
                            Log.Warn("Factor：" + detailCode + " 找不到污染物因子！");
                            continue;
                        }
                        var rtdDouble = Parser.GetFloatByKey(detailCode + "-Cou", content);
                        if (rtdDouble == null)
                        {
                            Log.Warn("Cou：没有Cou！");
                            continue;
                        }

                        var detail = contextTarget.data_hour.Where(t => t.main_id == master.id)
                            .FirstOrDefault(t => t.pollutant_code.Equals(detailCode));
                        if (detail == null)
                        {
                            detail = new data_hour();
                            contextTarget.data_hour.Add(detail);
                        }

                        detail.main_id = master.id;
                        detail.Cou = rtdDouble.Value;
                        detail.Min = Parser.GetFloatByKey(detailCode + "-Min", content);
                        detail.Avg = Parser.GetFloatByKey(detailCode + "-Avg", content);
                        detail.Max = Parser.GetFloatByKey(detailCode + "-Max", content);
                        detail.pollutant_code = factor.code;
                    }
                    contextTarget.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex);
                Log.Error(content);
            }
        }
        //日处理数据，并同步月处理数据，年处理数据
        public static void Process2031(string content)
        {
            try
            {
                var mn = Parser.GetStringByKey("MN", content);
                if (string.IsNullOrWhiteSpace(mn))
                {
                    return;
                }

                var port = Util.GetInfoFromMn(mn);
                if (port == null)
                {
                    Log.Warn("MN：" + mn + " 找不到对应企业排口！");
                    return;
                }
                var dataTime = Parser.GetDateTimeByKey("DataTime", content);
                if (dataTime == null)
                {
                    Log.Warn("没有时间！");
                    return;
                }

                var dataTimeValue = dataTime.Value;
                var pollutantCodes = Parser.GetPollutantCodes(content);

                using (var contextTarget = new PlatformVocContext())
                {
                    //todo:性能会有问题。
                    var master = contextTarget.data_day_main.Where(t => t.ps_code.Equals(port.ps_code)).Where(t => t.pi_code.Equals(port.port_code))
                        .FirstOrDefault(t => t.monitor_time == dataTimeValue);

                    if (master == null)
                    {
                        master = new data_day_main
                        {
                            mn = mn,
                            monitor_time = dataTimeValue,
                            is_synchronize = false,
                            ps_code = port.ps_code,
                            pi_code = port.port_code,
                            type = "voc"
                        };
                        contextTarget.data_day_main.Add(master);
                        contextTarget.SaveChanges();
                    }

                    foreach (var detailCode in pollutantCodes)
                    {
                        var factor = Util.GetFactor(detailCode);
                        if (factor == null)
                        {
                            Log.Warn("Factor：" + detailCode + " 找不到污染物因子！");
                            continue;
                        }
                        var rtdDouble = Parser.GetFloatByKey(detailCode + "-Cou", content);
                        if (rtdDouble == null)
                        {
                            Log.Warn("Cou：没有Cou！");
                            continue;
                        }
                        var detail = contextTarget.data_day.Where(t => t.main_id == master.id)
                                         .FirstOrDefault(t => t.pollutant_code.Equals(detailCode));
                        if (detail == null)
                        {
                            detail = new data_day();
                            contextTarget.data_day.Add(detail);
                        }

                        detail.main_id = master.id;
                        detail.Cou = rtdDouble.Value;
                        detail.Min = Parser.GetFloatByKey(detailCode + "-Min", content);
                        detail.Avg = Parser.GetFloatByKey(detailCode + "-Avg", content);
                        detail.Max = Parser.GetFloatByKey(detailCode + "-Max", content);
                        detail.pollutant_code = factor.code;
                    }
                    contextTarget.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex);
                Log.Error(content);
            }
        }
        //日处理数据，并同步月处理数据，年处理数据
        public static void Process2031Month(string content)
        {
            try
            {
                var mn = Parser.GetStringByKey("MN", content);
                if (string.IsNullOrWhiteSpace(mn))
                {
                    return;
                }

                var port = Util.GetInfoFromMn(mn);
                if (port == null)
                {
                    Log.Warn("MN：" + mn + " 找不到对应企业排口！");
                    return;
                }
                var dataTime = Parser.GetDateTimeByKey("DataTime", content);
                if (dataTime == null)
                {
                    Log.Warn("没有时间！");
                    return;
                }
                var dataTimeValue = dataTime.Value;
                var pollutantCodes = Parser.GetPollutantCodes(content);

                using (var contextTarget = new PlatformVocContext())
                {
                    //todo:性能会有问题。
                    var master = contextTarget.data_month_main.Where(t => t.ps_code.Equals(port.ps_code)).Where(t => t.pi_code.Equals(port.port_code))
                        .FirstOrDefault(t => t.monitor_time.Month == dataTimeValue.Month && t.monitor_time.Year == dataTimeValue.Year);

                    if (master == null)
                    {
                        master = new data_month_main
                        {
                            mn = mn,
                            monitor_time = dataTimeValue,
                            is_synchronize = false,
                            ps_code = port.ps_code,
                            pi_code = port.port_code,
                            type = "voc"
                        };
                        contextTarget.data_month_main.Add(master);
                        contextTarget.SaveChanges();
                    }
                    master.monitor_time = dataTimeValue;
                    var begin = Util.TrimToMonth(dataTime.Value, 0);
                    var end = Util.TrimToMonth(dataTime.Value, 1);
                    var dayMains = contextTarget.data_day_main.Where(t => t.mn.Equals(mn))
                        .Where(t => t.monitor_time >= begin).Where(t => t.monitor_time < end)
                        .Select(t => t.id).ToList();
                    if (dayMains == null || dayMains.Count < 1)
                    {
                        return;
                    }

                    foreach (var detailCode in pollutantCodes)
                    {
                        var factor = Util.GetFactor(detailCode);

                        if (factor == null)
                        {
                            Log.Warn("Factor：" + detailCode + " 找不到污染物因子！");
                            continue;
                        }
                        var newCode = factor.code;
                        var detail = contextTarget.data_month.Where(t => t.main_id == master.id)
                            .FirstOrDefault(t => t.pollutant_code.Equals(newCode));

                        var records = contextTarget.data_day.Where(t => dayMains.Contains(t.main_id))
                            .Where(t => t.pollutant_code.Equals(newCode));
                        if (records == null || records.Count() < 1)
                        {
                            continue;
                        }

                        if (detail == null)
                        {
                            detail = new data_month();
                            contextTarget.data_month.Add(detail);
                        }
                        var cou = records
                            .Sum(t => t.Cou);
                        detail.main_id = master.id;
                        detail.Cou = cou;
                        detail.Min = contextTarget.data_day.Where(t => dayMains.Contains(t.main_id))
                            .Where(t => t.pollutant_code.Equals(newCode))
                            .Min(t => t.Min);
                        detail.Avg = contextTarget.data_day.Where(t => dayMains.Contains(t.main_id))
                            .Where(t => t.pollutant_code.Equals(newCode))
                            .Average(t => t.Avg);
                        detail.Max = contextTarget.data_day.Where(t => dayMains.Contains(t.main_id))
                            .Where(t => t.pollutant_code.Equals(newCode))
                            .Max(t => t.Max);
                        detail.pollutant_code = factor.code;

                    }
                    contextTarget.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex);
                Log.Error(content);
            }
        }
        //日处理数据，并同步月处理数据，年处理数据
        public static void Process2031Year(string content)
        {
            try
            {
                var mn = Parser.GetStringByKey("MN", content);
                if (string.IsNullOrWhiteSpace(mn))
                {
                    return;
                }

                var port = Util.GetInfoFromMn(mn);
                if (port == null)
                {
                    Log.Warn("MN：" + mn + " 找不到对应企业排口！");
                    return;
                }
                var dataTime = Parser.GetDateTimeByKey("DataTime", content);
                if (dataTime == null)
                {
                    Log.Warn("没有时间！");
                    return;
                }
                var dataTimeValue = dataTime.Value;
                var pollutantCodes = Parser.GetPollutantCodes(content);

                using (var contextTarget = new PlatformVocContext())
                {
                    //todo:性能会有问题。
                    var master = contextTarget.data_year_main.Where(t => t.ps_code.Equals(port.ps_code)).Where(t => t.pi_code.Equals(port.port_code)).OrderByDescending(t => t.monitor_time)
                        .FirstOrDefault(t => t.monitor_time.Year == dataTimeValue.Year);

                    if (master == null)
                    {
                        master = new data_year_main
                        {
                            mn = mn,
                            monitor_time = dataTimeValue,
                            is_synchronize = false,
                            ps_code = port.ps_code,
                            pi_code = port.port_code,
                            type = "voc"
                        };
                        contextTarget.data_year_main.Add(master);
                        contextTarget.SaveChanges();
                    }
                    master.monitor_time = dataTimeValue;
                    var begin = Util.TrimToYear(dataTime.Value, 0);
                    var end = Util.TrimToYear(dataTime.Value, 1);
                    var dayMains = contextTarget.data_day_main.Where(t => t.mn.Equals(mn))
                        .Where(t => t.monitor_time >= begin).Where(t => t.monitor_time < end)
                        .Select(t => t.id).ToList();


                    foreach (var detailCode in pollutantCodes)
                    {
                        var factor = Util.GetFactor(detailCode);
                        if (factor == null)
                        {
                            Log.Warn("Factor：" + detailCode + " 找不到污染物因子！");
                            continue;
                        }
                        var newCode = factor.code;
                        var detail = contextTarget.data_year.Where(t => t.main_id == master.id)
                            .FirstOrDefault(t => t.pollutant_code.Equals(newCode));
                        var records = contextTarget.data_day.Where(t => dayMains.Contains(t.main_id))
                            .Where(t => t.pollutant_code.Equals(newCode));
                        if (records == null || records.Count() < 1)
                        {
                            continue;
                        }

                        if (detail == null)
                        {
                            detail = new data_year();
                            contextTarget.data_year.Add(detail);
                        }
                        var cou = records
                            .Sum(t => t.Cou);
                        detail.main_id = master.id;
                        detail.Cou = cou;
                        detail.Min = contextTarget.data_day.Where(t => dayMains.Contains(t.main_id))
                            .Where(t => t.pollutant_code.Equals(newCode))
                            .Min(t => t.Min);
                        detail.Avg = contextTarget.data_day.Where(t => dayMains.Contains(t.main_id))
                            .Where(t => t.pollutant_code.Equals(detailCode))
                            .Average(t => t.Avg);
                        detail.Max = contextTarget.data_day.Where(t => dayMains.Contains(t.main_id))
                            .Where(t => t.pollutant_code.Equals(newCode))
                            .Max(t => t.Max);
                        detail.pollutant_code = factor.code;

                    }
                    contextTarget.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex);
                Log.Error(content);
            }
        }
    }
}
